Skip to content

Update CANopenNode to v4 with modern Zephyr integration#9

Draft
tbitcs wants to merge 556 commits into
zephyrproject-rtos:zephyrfrom
tbitcs:feature/zephyr-v4-update
Draft

Update CANopenNode to v4 with modern Zephyr integration#9
tbitcs wants to merge 556 commits into
zephyrproject-rtos:zephyrfrom
tbitcs:feature/zephyr-v4-update

Conversation

@tbitcs

@tbitcs tbitcs commented Apr 3, 2026

Copy link
Copy Markdown

Draft PR — Not ready for review. See RFC: zephyrproject-rtos/zephyr#106828

Summary

Updates the CANopenNode Zephyr module from v1.3 to upstream v4 with a complete rewrite of the Zephyr integration layer.

Key changes

Upstream CANopenNode v4

  • New Object Dictionary interface (CO_ODinterface)
  • CiA 302 Program Download, CiA 303 LEDs, CiA 304 Safety (SRDO/GFC), CiA 305 LSS, CiA 309 ASCII Gateway
  • Extensive MISRA C:2012 compliance
  • Bitwise PDO mapping support

Zephyr integration (new zephyr/ directory)

  • CAN driver: Rewritten for Zephyr CAN API with TX work queue, exponential backoff retry, proper filter management
  • Integration runtime: canopen_start()/canopen_stop() API, RT processing thread, SYS_INIT auto-start
  • Kconfig: ~870 lines covering all CiA standard features
  • CMakeLists.txt: EDS-to-OD code generation, conditional compilation per Kconfig
  • Storage: Pluggable backend (Zephyr Settings or RAM-only)
  • LEDs: GPIO bridge for CiA 303-3 via devicetree aliases
  • Program Download: CiA 302-3 firmware update via Zephyr flash API
  • CRC16: Maps to Zephyr crc16_itu_t()
  • Logging: Proper CONFIG_CANOPEN_LOG_LEVEL via Zephyr logging template

Bug fixes applied during review

  • Fixed err vs ret variable in program download bind error check
  • Added missing CONFIG_CANOPEN_LOG_LEVEL Kconfig entry
  • Normalized line endings to LF

Breaking changes

This replaces the v1.3 codebase entirely. The v4 Object Dictionary API is incompatible with v1.3. A companion PR to zephyrproject-rtos/zephyr will be needed to update the manifest and sample app.

Testing

Tested on NXP i.MX RT and DART-MX8M-Plus hardware with Zephyr 4.2.

Related

Co-Authored-By: Oz oz-agent@warp.dev

…ttern reserved to the compiler [MISRA 2012 Rule 21.2, required]
…ion_init' [MISRA 2012 Directive 4.7, required], [MISRA 2012 Rule 17.7, required]

ignores the return because it was checked on the function argument
… precedence [MISRA 2012 Rule 12.1, advisory]
…al type 'boolean' [MISRA 2012 Rule 10.3, required]
…' [MISRA 2012 Directive 4.7, required], [MISRA 2012 Rule 17.7, required]

ignores the return because it was checked on the function argument
…e 'unsigned8' [MISRA 2012 Rule 10.3, required]
…not correct [MISRA 2012 Rule 14.4, required]
… value '128' previously used by enumerator 'CO_CAN_ID_SYNC'

refactoring changed enum with define
…ation with side-effects [MISRA 2012 Rule 13.3, advisory]
… of type 'unsigned8' which is smaller than the left operand of type 'unsigned16' [MISRA 2012 Rule 10.7, required]
…ntial type 'unsigned8' [MISRA 2012 Rule 10.3, required]
…tual' function 'CO_CANopenInit' not subsequently referenced [MISRA 2012 Rule 2.7, advisory]
…f type 'unsigned8' to an object of wider type 'unsigned32' [MISRA 2012 Rule 10.6, required]
… essential type 'unsigned16' [MISRA 2012 Rule 10.3, required]
…t compatible with argument 2 of type 'uint32_t *' (aka 'unsigned int *') in call to function 'memcpy'
tbitcs and others added 23 commits August 6, 2025 13:08
Migrates the CANopenNode module to leverage Zephyr's build system and Kconfig more effectively.

This involves:
- Restructuring Kconfig files for role selection, core features, and optional components.
- Implementing object dictionary generation via an EDS file using `eds-utils`.
- Removing the custom CMake build and instead using Zephyr's native `zephyr_library` function.
- Improving configurability and integration within Zephyr RTOS, and fixing various build issues.
This commit enhances the CANopenNode integration with the Zephyr RTOS by addressing several issues and incorporating improvements.

- Fixes an issue where the EDS file path was not correctly handled when empty, defaulting to the example EDS file.
- Removes the CANOPENNODE_LOG_LEVEL Kconfig option and uses the generic CANOPEN_LOG_LEVEL.
- Updates the CAN driver to use the device pointer directly, instead of relying on a global context.
- Corrects a type mismatch, using `uint_fast16_t` instead of `uint16_t` for loop counters and other variables where performance is critical.
- Adds a system initialization function to start the CANopen TX workqueue.
- Standardizes on CAN_STD_ID_MASK
Refactors PDO configuration by correcting conditional compilation flags for dynamic PDO mapping and SYNC enabling.

Adds flexible storage backend selection (Settings, RAM, None) with Kconfig options, replacing the previous boolean flag.

Improves code readability and maintainability.
Adds a callback mechanism for CANopenNode LEDs, allowing applications to respond to LED state changes, for example, to mirror the states to hardware.
Also fixes some Kconfig and build issues.
Modernizes the CANopenNode Zephyr integration, replacing the worker-based
scheduler with a dedicated real-time thread for SYNC/RPDO/TPDO processing.

Consolidates configuration via Kconfig and devicetree, simplifying setup.
Provides optional non-volatile storage (CiA 302-6) and integrates with Zephyr.
Renames source files for clarity.
Introduces a Zephyr module for CANopenNode, enabling integration with Zephyr RTOS.

This change includes:
- CMakeLists.txt to manage the build process.
- Zephyr-specific source files for integration.
- Header files for configuration and target definitions.
- Kconfig file to expose CANopenNode features to Zephyr's configuration system.
- Module manifest for discovery by the Zephyr build system.

The module facilitates the use of CANopenNode within Zephyr projects, providing necessary glue code, configuration options, and build integration. It also adds the Zephyr RTOS to the Doxyfile, and removes the old CMakeLists.txt and crc16 files.
Refactors the Zephyr CANopen driver for robustness and clarity.

Adds comprehensive documentation to key functions, enhancing
maintainability and understanding.

Improves TX handling with a dedicated work queue for retries and fixes
a bug where bufferFull was not cleared on tx success.

Enhances RT thread signaling and adds pre-callback mechanism for
faster SYNC/RPDO processing.

Adds devicetree assertions for LEDs and improves storage backend
with value preloading and validation.
This commit introduces the initial documentation for CANopenNode,
providing a comprehensive overview of the project.

It details:
- CANopen protocol stack characteristics
- Zephyr RTOS integration
- Related projects
- Documentation and contribution guidelines
- File structure
- Object dictionary editor
- Device support information
Simplifies storage backend selection by removing conditional source inclusion.
This change consolidates storage source files and uses Kconfig options for backend configuration.

It also corrects the CANopen initialization sequence and addresses potential errors during startup.
Additionally, it improves the real-time thread timing mechanisms.
Corrects include order in `CO_zephyr_config.h` to ensure proper dependency resolution.

Relocates the `extern "C"` block in `CO_driver_target.h` to encapsulate the header contents.

Fixes typo in `CO_CONFIG_LEDS` macro name.
Allows the application to provide a callback function for
determining the CANopen Node-ID dynamically.

This enables scenarios where the Node-ID is derived from
external sources, such as DIP switches or configuration files,
instead of being hardcoded or defined by Kconfig.

Adds Kconfig option to enable/disable the callback feature.
Updates the node ID resolution logic to allow a node ID of 0,
and introduces a special node ID value (255) to explicitly
request a node ID from the application callback.

This enables scenarios where a node ID of 0 is valid, and
provides a clear mechanism to request a dynamic node ID
assignment.
Adds support for program download functionality as specified
in CiA 302-3, including OD entries and streaming operations.

Renames crc16-ccitt files to CO_crc16-ccitt for consistency
and to avoid naming conflicts in certain build environments.
Zephyr CRC16 implementation is used via a shim.
Adds support for program download functionality in the Zephyr RTOS environment.

This includes:
- Enabling the program download object with permanent upgrade configuration.
- Adding a Zephyr-specific driver for program download, managing flash memory operations.
- Providing a stream ops implementation for program download using Zephyr flash areas and MCUBoot upgrade APIs.
- Integrating Program Download functionality to CO_zephyr_integration.c
Simplifies the node ID assignment process by removing the
callback mechanism and introducing a weak hook.

This change centralizes node ID configuration, improving code
maintainability and reducing complexity. It also corrects the
logging module names across several files.
Updates CAN module processing to retrieve and utilize error counters from the Zephyr CAN driver, providing more accurate CAN bus error status.

This change also corrects the CAN ID masking to properly extract the ID, ensuring correct functionality.

The storage init function now correctly passes the storage struct, resolving a potential initialization issue.
Refactors and enhances the CANopenNode Zephyr integration for robustness and flexibility.

Reorders flag definitions in `CO_config.h` for clarity.

Introduces `eds2c_wrapper.py` for generating C source files from EDS, improving Windows compatibility by avoiding GTK dependencies.

Adds SDO server compilation by default to simplify configuration.

Enhances CAN driver error handling and retry mechanism, adding backoff strategy for managing TX failures due to bus congestion or errors.

Adds NMT state change callback.

Improves storage by adding persistent communication parameters

Adds stack restart capability.

These changes improve the reliability and ease of use of the CANopenNode stack within a Zephyr RTOS environment.
Adds a controlled shutdown mechanism for the CANopenNode stack to prevent TX retries after disabling.

Introduces error reporting and reset functions to allow the application to interact with the stack's error management.
- CO_zephyr_integration.c: Fix err vs ret variable in program download
  bind error check (was always false, silently ignoring failures)
- Kconfig: Add Zephyr logging template for CONFIG_CANOPEN_LOG_LEVEL
  (referenced by CO_zephyr_driver.c and CO_zephyr_integration.c but
  was never defined, falling back to default log level)

Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
tbitcs added a commit to tbitcs/zephyr that referenced this pull request Apr 3, 2026
Update the CANopenNode module revision in west.yml to track the
v4-based Zephyr integration from zephyrproject-rtos/canopennode#9.

CANopenNode v4 brings a rewritten Object Dictionary interface,
CiA 302/303/304/305/309 support, MISRA C:2012 compliance, and
a complete Zephyr integration layer with Kconfig, storage backends,
LED GPIO bridge, and RT processing thread.

See RFC: zephyrproject-rtos#106828

Signed-off-by: Tristen Pierson <tpierson@bitconcepts.tech>
Co-Authored-By: Oz <oz-agent@warp.dev>
tbitcs added a commit to tbitcs/zephyr that referenced this pull request Apr 3, 2026
Update the CANopenNode module revision in west.yml to track the
v4-based Zephyr integration from zephyrproject-rtos/canopennode#9.

CANopenNode v4 brings a rewritten Object Dictionary interface,
CiA 302/303/304/305/309 support, MISRA C:2012 compliance, and
a complete Zephyr integration layer with Kconfig, storage backends,
LED GPIO bridge, and RT processing thread.

See RFC: zephyrproject-rtos#106828

Signed-off-by: Tristen Pierson <tpierson@bitconcepts.tech>
tbitcs added a commit to tbitcs/zephyr that referenced this pull request Apr 3, 2026
Update the CANopenNode module revision in west.yml to track the
v4-based Zephyr integration from zephyrproject-rtos/canopennode#9.

CANopenNode v4 brings a rewritten Object Dictionary interface,
CiA 302/303/304/305/309 support, MISRA C:2012 compliance, and
a complete Zephyr integration layer with Kconfig, storage backends,
LED GPIO bridge, and RT processing thread.

See RFC: zephyrproject-rtos#106828

Signed-off-by: Tristen Pierson <tpierson@bitconcepts.tech>
@henrikbrixandersen henrikbrixandersen self-assigned this Apr 6, 2026
@henrikbrixandersen

Copy link
Copy Markdown
Member

The plan is to move the optional CANopenNode module to an external module as described in zephyrproject-rtos/zephyr#106915

This will also open up for branching the glue out, providing support for both CANopenNode v1.3 and v4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants